package com.bjtang.book.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjtang.book.dto.ArticleDto;
import com.bjtang.book.dto.IdDto;
import com.bjtang.book.dto.ReturnDto;
import com.bjtang.book.entiy.ArticleBody;
import com.bjtang.book.entiy.ArticleHead;
import com.bjtang.book.entiy.BrowseTable;
import com.bjtang.book.myexception.DataCheckException;
import com.bjtang.book.service.ArticleBodyService;
import com.bjtang.book.service.ArticleHeadService;
import com.bjtang.book.service.BrowseService;
import com.bjtang.book.service.MyService;
import com.bjtang.book.service.SysUserDtoService;
import com.bjtang.book.util.ReturnUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @类名 ArticleController.java
 * @说明 文章控制器
 * @作者 唐帮杰
 * @时间 2019年6月22日下午9:00:37
 */
@Api(tags = "文章综合管理")
@Validated
@RestController
@RequestMapping(value = "/article/")
@Transactional(rollbackFor = Exception.class)
public class ArticleController {
	@Autowired
	ArticleHeadService articleHeadService;
	@Autowired
	ArticleBodyService articleBodyService;
	@Autowired
	SysUserDtoService sysUserDtoService;
	@Autowired
	BrowseService browseService;
	@Autowired
	private MyService myService;

	@ApiOperation("新建指定文章")
	@PostMapping("/")
	public ReturnDto InsertArticle(@RequestBody @Valid ArticleDto articleDto) {
		// 注入创建人
		articleDto.setFounder(myService.getMyselfId());
		ArticleHead head = articleDto.getHead();
		boolean save = articleHeadService.save(head);
		articleDto.setArticleNumber(head.getArticleNumber());
		boolean save2 = false;
		if (save)
			save2 = articleBodyService.save(articleDto.getBody());
		return ReturnUtil.successOrError(save && save2, "");
	}

	@ApiOperation("给指定文章点赞")
	@PutMapping("/up/")
	public ReturnDto editArticleByUp(@RequestBody @Valid IdDto articleId) {
		checkArticle(articleId.getId(), "up");
		return ReturnUtil.success();
	}

	@ApiOperation("给指定文章点踩")
	@PutMapping("/down/")
	public ReturnDto editArticleByDown(@RequestBody @Valid IdDto articleId) {
		checkArticle(articleId.getId(), "down");
		return ReturnUtil.success();
	}

	@ApiOperation("更新指定文章正文")
	@PutMapping("/")
	public ReturnDto editArticle(@RequestBody @Valid ArticleBody articleBody) {
		checkArticle(articleBody.getArticleNumber(), "check");
		// 注入更新人
		articleBody.setUpdateBy(myService.getMyselfId());
		return ReturnUtil.successOrError(articleBodyService.saveOrUpdate(articleBody), articleBody);
	}

	@ApiOperation("删除指定文章")
	@DeleteMapping("/")
	public ReturnDto delArticle(@RequestBody @Valid IdDto articleId) {
		checkArticle(articleId.getId(), "check");
		return ReturnUtil.successOrError(articleHeadService.removeById(articleId.getId()), articleId.getId());
	}

	@ApiOperation("查询文章头列表ByUser")
	@GetMapping("/by-user/{userId}")
	public ReturnDto GetArticleByUser(@PathVariable Long userId) {
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getFounder, userId)
				.eq(ArticleHead::getStatus, 0).orderByDesc(ArticleHead::getArticleNumber).list());
	}

	@SuppressWarnings("unchecked")
	@ApiOperation("查询文章头列表ByTop 最火的前5个")
	@GetMapping("/by-top/")
	public ReturnDto GetArticleByTop() {
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getStatus, 0)
				.orderByDesc(ArticleHead::getTraffic, ArticleHead::getUpNumber, ArticleHead::getRecommendNumber)
				.last("limit 5").list());
	}

	@ApiOperation("查询文章头列表ByNew 最新的")
	@GetMapping("/by-new/{current}/{size}")
	public ReturnDto GetArticleByNew(@PathVariable Long current, @PathVariable Long size) {
		Page<ArticleHead> page = new Page<ArticleHead>(current, size);
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getStatus, 0)
				.orderByDesc(ArticleHead::getArticleNumber).page(page));
	}

	@ApiOperation("查询文章头列表ByFindString")
	@GetMapping("/by-find/{findString}/{current}/{size}")
	public ReturnDto GetArticleByFingStringPage(@PathVariable String findString, @PathVariable Long current,
			@PathVariable Long size) {
		Page<ArticleHead> page = new Page<ArticleHead>(current, size);
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getStatus, 0)
				.like(ArticleHead::getTitle, findString).or().like(ArticleHead::getSummary, findString)
				.orderByDesc(ArticleHead::getArticleNumber).page(page));
	}

	@ApiOperation("查询文章头列表ByIds")
	@PostMapping("/by-ids/")
	public ReturnDto GetArticleByIdList(@RequestBody @Valid List<Long> articleIdList) {
		articleIdList.add(0L);
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getStatus, 0)
				.in(ArticleHead::getArticleNumber, articleIdList).orderByDesc(ArticleHead::getArticleNumber).list());
	}

	@ApiOperation("查询文章头列表ByUserPage")
	@GetMapping("/by-user/{userId}/{current}/{size}")
	public ReturnDto GetArticleByUserPage(@PathVariable Long userId, @PathVariable Long current,
			@PathVariable Long size) {
		Page<ArticleHead> page = new Page<ArticleHead>(current, size);
		return ReturnUtil.success(articleHeadService.lambdaQuery().eq(ArticleHead::getFounder, userId)
				.eq(ArticleHead::getStatus, 0).orderByDesc(ArticleHead::getArticleNumber).page(page));
	}

	@ApiOperation("查询指定文章ById")
	@GetMapping("/by-article/{articleId}")
	public ReturnDto GetArticleById(@PathVariable Long articleId) {
		ArticleHead findArticle = checkArticle(articleId, "find");
		ArticleBody byId = articleBodyService.getById(articleId);
		String selectUserNameById = sysUserDtoService.selectUserNameById(findArticle.getFounder());
		ArticleDto articleDto = new ArticleDto();
		articleDto.setHead(findArticle);
		articleDto.setBody(byId);
		articleDto.setFounderName(selectUserNameById);
		return ReturnUtil.success(articleDto);
	}

	// 权限校验
	ArticleHead checkArticle(Long articleId, String size) {
		ArticleHead byId = articleHeadService.getById(articleId);
		if (byId == null)
			throw new DataCheckException("文章没找到");
		System.err.println(byId.toString());
		if (byId.getStatus() == 1)
			throw new DataCheckException("文章已失效");
		// 权限检查
		if ("check".equals(size))
			if (byId.getFounder().longValue() != myService.getMyselfId().longValue())
				throw new DataCheckException("没有操作权限");
		// 查询
		if ("find".equals(size)) {
			BrowseTable browseTable = new BrowseTable();
			browseTable.setArticleNumber(byId.getArticleNumber());
			browseTable.setFounder(myService.getMyselfId());
			browseTable.setUpDownIs(2);
			browseService.save(browseTable);

			byId.setTraffic(byId.getTraffic() + 1);
			articleHeadService.saveOrUpdate(byId);
		}
		// 点赞
		if ("up".equals(size)) {
			List<BrowseTable> list = browseService.lambdaQuery()
					.eq(BrowseTable::getArticleNumber, byId.getArticleNumber()).eq(BrowseTable::getUpDownIs, 0)
					.eq(BrowseTable::getFounder, myService.getMyselfId()).list();
			if (list.size() != 0)
				throw new DataCheckException("你已经点过赞了");
			
			BrowseTable browseTable = new BrowseTable();
			browseTable.setArticleNumber(byId.getArticleNumber());
			browseTable.setFounder(myService.getMyselfId());
			browseTable.setUpDownIs(0);
			browseService.save(browseTable);		
			byId.setUpNumber(byId.getUpNumber() + 1);
			articleHeadService.saveOrUpdate(byId);
		}
		// 点踩
		if ("down".equals(size)) {
			List<BrowseTable> list = browseService.lambdaQuery()
					.eq(BrowseTable::getArticleNumber, byId.getArticleNumber()).eq(BrowseTable::getUpDownIs, 1)
					.eq(BrowseTable::getFounder, myService.getMyselfId()).list();
			if (list.size() != 0)
				throw new DataCheckException("你已经点过踩了");

			BrowseTable browseTable = new BrowseTable();
			browseTable.setArticleNumber(byId.getArticleNumber());
			browseTable.setFounder(myService.getMyselfId());
			browseTable.setUpDownIs(1);
			browseService.save(browseTable);
			
			byId.setDownNumber(byId.getDownNumber() + 1);
			articleHeadService.saveOrUpdate(byId);
		}
		return byId;
	}

}
